<?php
namespace Reezy\OAuth\Driver;

use Reezy\OAuth\OAuthBase;
use Reezy\OAuth\OAuthException;
use Reezy\OAuth\OAuthInfo;


class OAuthWechat extends OAuthBase
{

    const BASE_URL = 'https://api.weixin.qq.com/sns';

    public function isSupportSilentMode(): bool
    {
        return $this->scope === 'snsapi_base';
    }


    public function getAuthUrl(string $redirectUri = null, string $state = null, bool $isSilent = false): string
    {
        $scope = $this->scope ?? 'snsapi_base';

        switch ($scope) {
            case 'snsapi_login':
                $path = 'qrconnect';
                break;
            case 'snsapi_base':
                $path = 'oauth2/authorize';
                if (!$isSilent) {
                    $scope = 'snsapi_userinfo';
                }
                break;
            case 'snsapi_userinfo':
                $path = 'oauth2/authorize';
                break;
        }


        return self::buildUrl("https://open.weixin.qq.com/connect/{$path}", [
                'appid' => $this->clientId,
                'redirect_uri' => $redirectUri ?? $this->redirectUri,
                'response_type' => 'code',
                'scope' => $scope,
                'state' => $state,
                'connect_redirect' => 1,
            ]) . "#wechat_redirect";
    }

    public function getAccessToken($code): OAuthInfo
    {
        $info = $this->httpPost(self::BASE_URL . '/oauth2/access_token', [
            'appid' => $this->clientId,
            'secret' => $this->clientSecret,
            'code' => $code,
            'grant_type' => 'authorization_code',
        ]);
        return OAuthInfo::token($info);
    }

    public function getUserInfo(OAuthInfo $token): OAuthInfo
    {
        $token->checkOpenId();

        $info = $this->httpGet(self::BASE_URL . '/userinfo', [
            'access_token' => $token->getAccessToken(),
            'openid' => $token->getOpenId(),
            'lang' => 'zh_cn',
        ]);

        if (!empty($info['errcode'])) {
            throw new OAuthException("[{$info['errcode']}] {$info['errmsg']}");
        }

        return OAuthInfo::userinfo($info, 'nickname', 'headimgurl');
    }
}
